'''
@Project ：conda_envs 
@File    ：MySerial.py
@IDE     ：PyCharm 
@Author  ：子协
@Date    ：2024-11-17 22:05 
'''
import serial
import time
from PyQt5.QtCore import QThread, pyqtSignal


class MySerial(QThread):
    data_received_signal = pyqtSignal()  # 接收到大包信号

    def __init__(self, parent=None):
        super(MySerial, self).__init__(parent)
        self.SerialisOpen = False  # 串口是否打开
        self.ThreadisRunning = False  # 读取数据线程是否运行
        self.DataisSynchronous = False  # 数据是否同步
        self.OneFrameMsg = []  # 一帧数据
        self.Temp_OneFrameMsg = []  # 一帧数据缓冲区

    def open(self, port, baudrate=57600):
        try:
            self.ser = serial.Serial(port, baudrate)  # 打开COM17，将波特率配置为57600，其余参数使用默认值
            if self.ser.isOpen():  # 判断串口是否成功打开
                self.SerialisOpen = True
                # print("打开串口成功")
                # print(self.ser.name)  # 输出串口号
                return True
            else:
                self.SerialisOpen = False
                return False
                # print("Error!")
        except:
            self.SerialisOpen = False
            return False

    def close(self):
        if self.SerialisOpen:
            self.ser.close()
            self.SerialisOpen = False
            self.DataisSynchronous = False
            self.ThreadisRunning = False
    def pause(self):
        self.ThreadisRunning = False
        self.DataisSynchronous = False
        self.OneFrameMsg.clear()
        self.Temp_OneFrameMsg.clear()

    def resume(self):
        self.ThreadisRunning = True

    def Synchronous(self):
        # 开始同步
        b = self.ser.read(3)                                # 非阻塞读取
        if len(b)>0:
            print("Synchronous is running...")
            while b[0] != 170 or b[1] != 170 or b[2] != 4:
                # print(b[0], b[1], b[2])
                b = self.ser.read(3)
            b = self.ser.read(5)
            print("Synchronous is ok!")
            # 同步结束
            self.DataisSynchronous = True

    def run(self):
        while True:
            if self.ThreadisRunning and self.DataisSynchronous:  # 如果线程正在运行  且  已经同步 则读取数据
                # print("读取数据中...")
                com_input = self.ser.read(8)
                if com_input:  # 如果读取结果非空，则输出
                    if com_input[0] == 170 and com_input[1] == 170 and com_input[2] == 4 and com_input[3] == 128 and \
                            com_input[4] == 2:  # 小包
                        xxHigh = com_input[5]  # 原始数据高位
                        xxLow = com_input[6]  # 原始数据低位
                        xxCheckSum = com_input[7]  # 原始数据校验位
                        xxRawWave = xxHigh << 8 | xxLow  # 原始数据
                        CheckSum = ((0x80 + 0x02 + xxHigh + xxLow) & 0xFF) ^ 0xFF  # 根据原始数据计算出的校验值
                        if xxRawWave > 32768:
                            xxRawWave -= 65536
                        # xxRawWave = xxRawWave*(1.8/4096)
                        if xxCheckSum == CheckSum:
                            self.Temp_OneFrameMsg.append(xxRawWave)
                        else:  # 传输出错
                            self.Temp_OneFrameMsg.append(-1)
                            print("Error:RawData is invalid")
                    elif com_input[0] == 170 and com_input[1] == 170 and com_input[2] == 32:  # 大包
                        big_msg = self.ser.read(28)
                        com_input += big_msg
                        ByteSums = 0
                        for i in range(3, 35):
                            ByteSums += com_input[i]
                        xxCheckSum = com_input[-1]  # 原始数据
                        CheckSum = (ByteSums & 0xFF) ^ 0xFF  # 根据原始数据计算出的校验值
                        if xxCheckSum == CheckSum:
                            self.Temp_OneFrameMsg.append(
                                (com_input[7] << 16) | (com_input[8] << 8) | (com_input[9] << 0))
                            self.Temp_OneFrameMsg.append(
                                (com_input[10] << 16) | (com_input[11] << 8) | (com_input[12] << 0))
                            self.Temp_OneFrameMsg.append(
                                (com_input[13] << 16) | (com_input[14] << 8) | (com_input[15] << 0))
                            self.Temp_OneFrameMsg.append(
                                (com_input[16] << 16) | (com_input[17] << 8) | (com_input[18] << 0))
                            self.Temp_OneFrameMsg.append(
                                (com_input[19] << 16) | (com_input[20] << 8) | (com_input[21] << 0))
                            self.Temp_OneFrameMsg.append(
                                (com_input[22] << 16) | (com_input[23] << 8) | (com_input[24] << 0))
                            self.Temp_OneFrameMsg.append(
                                (com_input[25] << 16) | (com_input[26] << 8) | (com_input[27] << 0))
                            self.Temp_OneFrameMsg.append(
                                (com_input[28] << 16) | (com_input[29] << 8) | (com_input[30] << 0))
                            self.Temp_OneFrameMsg.append(com_input[4])  # 信号强度
                            self.Temp_OneFrameMsg.append(com_input[32])  # 专注度
                            self.Temp_OneFrameMsg.append(com_input[34])  # 放松度
                        else:  # 传输出错
                            for i in range(0, 11):
                                self.Temp_OneFrameMsg.append(-1)
                            print("Error:BigPack value invalid\n")
                        self.OneFrameMsg = self.Temp_OneFrameMsg[:]
                        self.Temp_OneFrameMsg.clear()

                        self.data_received_signal.emit()  # 发射信号

            elif self.ThreadisRunning and not self.DataisSynchronous:  # 如果线程启动  且  没有同步 则同步
                print("数据同步中...")
                self.Synchronous()
            else:  # 线程暂停
                print("线程已暂停...")
                time.sleep(0.1)
